/*
 * SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
 *
 * SPDX-License-Identifier: MulanPSL-2.0
 */
#![allow(
    dead_code,
    mutable_transmutes,
    unused_variables,
    non_camel_case_types,
    non_snake_case,
    non_upper_case_globals,
    unused_assignments,
    unused_mut
)]

use crate::common::*;

pub type size_t = libc::c_ulong;

#[derive(Copy, Clone)]
#[repr(C)]
pub struct rcstr {
    pub refcnt: libc::c_int,
    pub str_0: [libc::c_char; 1],
}

extern "C" {
    fn strlen(_: *const libc::c_char) -> libc::c_ulong;
    static mut sudoers_subsystem_ids: [libc::c_uint; 0];
    fn memcpy(_: *mut libc::c_void, _: *const libc::c_void, _: libc::c_ulong) -> *mut libc::c_void;
    fn malloc(_: libc::c_ulong) -> *mut libc::c_void;
}

#[no_mangle]
pub fn rcstr_dup(mut src: *const libc::c_char) -> *mut libc::c_char {
    unsafe {
        let mut len: size_t = strlen(src);
        let mut dst: *mut libc::c_char = std::ptr::null_mut::<libc::c_char>();
        debug_decl!(SUDOERS_DEBUG_UTIL!());

        dst = rcstr_alloc(len);
        memcpy(dst as *mut libc::c_void, src as *const libc::c_void, len);
        *dst.offset(len as isize) = '\u{0}' as libc::c_char;

        debug_return_ptr!(dst);
    } //unsafe
}

#[no_mangle]
pub fn rcstr_alloc(mut len: size_t) -> *mut libc::c_char {
    let mut rcs: *mut rcstr = std::ptr::null_mut::<rcstr>();
    unsafe {
        debug_decl!(SUDOERS_DEBUG_UTIL!());

        rcs = malloc((::std::mem::size_of::<rcstr>() as libc::c_ulong).wrapping_add(len))
            as *mut rcstr;
        if rcs.is_null() {
            return std::ptr::null_mut::<libc::c_char>();
        }

        (*rcs).refcnt = 1;
        *((*rcs).str_0).as_mut_ptr().offset(0_isize) = '\u{0}' as i32 as libc::c_char;

        debug_return_ptr!((*rcs).str_0.as_mut_ptr());
    } //unsafe
}

#[no_mangle]
pub fn rcstr_addref(mut s: *const libc::c_char) -> *mut libc::c_char {
    let mut rcs: *mut rcstr = std::ptr::null_mut::<rcstr>();
    unsafe {
        debug_decl!(SUDOERS_DEBUG_UTIL!());

        if s.is_null() {
            debug_return_ptr!(std::ptr::null_mut::<libc::c_char>());
        }

        rcs = (s as *const libc::c_void as *mut libc::c_char).offset(-(4 as libc::c_ulong as isize))
            as *mut rcstr;
        (*rcs).refcnt += 1;

        debug_return_ptr!((*rcs).str_0.as_mut_ptr());
    } //unsafe
}

#[no_mangle]
pub fn rcstr_delref(mut s: *const libc::c_char) {
    let mut rcs: *mut rcstr = std::ptr::null_mut::<rcstr>();
    unsafe {
        debug_decl!(SUDOERS_DEBUG_UTIL!());

        if !s.is_null() {
            rcs = (s as *const libc::c_void as *mut libc::c_char)
                .offset(-(4 as libc::c_ulong as isize)) as *mut rcstr;
            (*rcs).refcnt -= 1;
            if (*rcs).refcnt == 0 as libc::c_int {
                *((*rcs).str_0)
                    .as_mut_ptr()
                    .offset(0 as libc::c_int as isize) = '\u{0}' as i32 as libc::c_char;
                free(rcs as *mut libc::c_void);
            }
        }

        debug_return!();
    } //unsafe
}
